package vip.specimen.system.common.component;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import vip.specimen.system.common.annotation.SystemJurisdiction;
import vip.specimen.system.datasource.entity.SystemPermissionEntity;
import vip.specimen.system.service.SystemPermissionService;
import vip.specimen.system.service.SystemUserService;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.*;

/**
 * *@Author: 余浪人
 * *@Date：2021/2/22 15:27
 * *@Email:yulangren520@Gmail.com
 * *@QQ:1368419640
 **/
@Component
@Slf4j
public class MyApplicationRunner implements ApplicationRunner {
    @Resource
    private SystemUserService systemUserService;
    @Resource
    private WebApplicationContext webApplicationContext;
    @Resource
    private SystemPermissionService permissionService;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("系统启动成功，数据初始化...");
        RequestMappingHandlerMapping mapping = webApplicationContext.getBean(RequestMappingHandlerMapping.class);
        final Map<String, Object> beansWithAnnotation = webApplicationContext.getBeansWithAnnotation(Api.class);
        Map<RequestMappingInfo, HandlerMethod> mappingHandlerMethods = mapping.getHandlerMethods();
        Set<Map<String,Object>> list = new HashSet<>();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> ma : mappingHandlerMethods.entrySet()) {
            RequestMappingInfo info = ma.getKey();
            HandlerMethod method = ma.getValue();
            Class clazz = Class.forName(method.getMethod().getDeclaringClass().getName());            //获取类对象
            String metName = method.getMethod().getName();// 方法名
            Method[] clazzDeclaredMethods = clazz.getDeclaredMethods();
            String url = info.getActivePatternsCondition().toString().replace("[", "").replace("]", "");
            Arrays.stream(clazzDeclaredMethods).forEach(
                    c -> {
                        if (c.getName().equals(metName)) {
                            String tag = "";
                            try {
                                tag = AnnotationUtils.findAnnotation(beansWithAnnotation.get(this.lowerFirst(clazz.getSimpleName())).getClass(), Api.class).tags()[0];
                            } catch (Exception e) {
                            }
                            RequiresPermissions requiresPermissions = c.getAnnotation(RequiresPermissions.class);
                            try {
                                ApiOperation annotation = c.getAnnotation(ApiOperation.class);
                                SystemJurisdiction jurisdiction = c.getAnnotation(SystemJurisdiction.class);
                                if (null != annotation && null != requiresPermissions.value()[0]) {
                                    Map<String, Object> map = new HashMap<>();
                                    map.put("parenId", tag);
                                    map.put("permission", new SystemPermissionEntity(jurisdiction.permissionName(), jurisdiction.resourceType(), url, requiresPermissions.value()[0], null));
                                    list.add(map);
                                }
                            } catch (Exception e) {

                            }
                        }
                    }
            );

        }

        this.permissionService.insert(list);
        this.systemUserService.initialize();
        log.info("系统准备就绪，欢迎使用！");
    }

    /**
     * 字符串首字母小写
     *
     * @param name 字符串
     * @return 结果
     */
    private String lowerFirst(String name) {
        char[] chars = name.toCharArray();
        chars[0] += 32;
        return String.valueOf(chars);
    }
}
